package files

import (
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
)

// ReadFile2String 读取文件内容并返回字符串。
//
// 参数:
//   - filePath: 文件路径
//
// 返回值:
//   - string: 文件内容字符串
//
// 注意:
//   - 如果读取失败返回空字符串并打印错误
func ReadFile2String(filePath string) string {
	b, err := ioutil.ReadFile(filePath)
	if err != nil {
		fmt.Print(err)
		return ""
	}

	return string(b)
}

// FileModTimestamp 获取文件的修改时间戳(Unix时间戳)。
//
// 参数:
//   - path: 文件路径
//
// 返回值:
//   - int64: Unix时间戳
//
// 注意:
//   - 如果获取失败返回0
func FileModTimestamp(path string) int64 {
	f, err := os.Open(path)
	if err != nil {
		return 0
	}
	defer f.Close()

	fi, err := f.Stat()
	if err != nil {
		return 0
	}

	return fi.ModTime().Unix()
}

// FileMove 移动文件到新位置。
//
// 参数:
//   - source: 源文件路径
//   - target: 目标文件路径
//
// 返回值:
//   - error: 移动过程中出现的错误
//
// 注意:
//   - 如果目标目录不存在会自动创建
//   - 支持绝对路径和相对路径
func FileMove(source string, target string) (err error) {
	if target == "" {
		return nil
	}
	source, err = filepath.Abs(source)
	if err != nil {
		return err
	}
	target, err = filepath.Abs(target)
	if err != nil {
		return err
	}
	revoke := false
	dir := filepath.Dir(target)
Redirect:
	_, err = os.Stat(dir)
	if err != nil {
		err = os.MkdirAll(dir, 0o755)
		if err != nil {
			return err
		}
		if !revoke {
			revoke = true
			goto Redirect
		}
	}
	return os.Rename(source, target)
}

// DeLFile 删除文件或目录。
//
// 参数:
//   - filePath: 要删除的文件或目录路径
//
// 返回值:
//   - error: 删除过程中出现的错误
//
// 注意:
//   - 会递归删除目录及其内容
func DeLFile(filePath string) error {
	return os.RemoveAll(filePath)
}

// Check file path exist.
// FileExist 检查文件或目录是否存在。
//
// 参数:
//   - path: 文件或目录路径
//
// 返回值:
//   - bool: 如果存在返回true
func FileExist(path string) bool {
	_, err := os.Lstat(path)
	return !os.IsNotExist(err)
}
